/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.facebook.fresco.samples.showcase.imagepipeline;

import ohos.annotation.Nullable;
import com.facebook.common.references.CloseableReference;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.controller.ControllerListener;
import com.facebook.drawee.drawable.Animatable;
import com.facebook.drawee.view.SimpleDraweeView;
import com.facebook.fresco.samples.showcase.ResourceTable;
import com.facebook.fresco.samples.showcase.imagepipeline.widget.ResizableStackLayout;
import com.facebook.fresco.samples.showcase.misc.ImageUriProvider;
import com.facebook.imagepipeline.common.ImageDecodeOptions;
import com.facebook.imagepipeline.decoder.ImageDecoder;
import com.facebook.imagepipeline.image.*;
import com.facebook.imagepipeline.platform.PlatformDecoder;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import com.oszc.bbhmlibrary.utils.LogUtil;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.utils.Rect;
import ohos.media.image.PixelMap;
import ohos.utils.net.Uri;

public class ImagePipelineRegionDecodingAbility extends Ability {

    private static final String TAG = "ImagePipelineRegionDecodingAbility";
    private SimpleDraweeView mFullDraweeView;
    private ResizableStackLayout mSelectedRegion;
    private SimpleDraweeView mRegionDraweeView;
    private Uri mUri;
    private @Nullable
    ImageInfo mImageInfo;

    private final ControllerListener<ImageInfo> mControllerListener =
            new BaseControllerListener<ImageInfo>() {
                @Override
                public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
                    mImageInfo = imageInfo;
                    mSelectedRegion.setUpdateMaximumDimensionOnNextSizeChange(true);
                    if (imageInfo != null) {
                        mFullDraweeView.setAspectRatio(imageInfo.getWidth() / (float) imageInfo.getHeight());
                        mFullDraweeView.invalidate();
                        updateRegion();
                    }
                }
            };

    private final ResizableStackLayout.SizeChangedListener mSizeChangedListener =
            (widthPx, heightPx) -> {
                updateRegion();
            };

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_layout_imagepipeline_region_decoding);

        mUri = ImageUriProvider.createSampleUri(ImageUriProvider.ImageSize.L, ImageUriProvider.Orientation.LANDSCAPE, null);

        mFullDraweeView = (SimpleDraweeView) findComponentById(ResourceTable.Id_drawee_view_full);
        mFullDraweeView.setController(
                Fresco.newDraweeControllerBuilder()
                        .setUri(mUri)
                        .setControllerListener(mControllerListener)
                        .build());

        mSelectedRegion = (ResizableStackLayout) findComponentById(ResourceTable.Id_frame_main);
        mSelectedRegion.init(findComponentById(ResourceTable.Id_btn_resize));
        mSelectedRegion.setSizeChangedListener(mSizeChangedListener);

        mRegionDraweeView = (SimpleDraweeView) findComponentById(ResourceTable.Id_drawee_view_region);
        mRegionDraweeView.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                updateRegion();
            }
        });
    }

    private void updateRegion() {
        if (mImageInfo == null) {
            return;
        }
        int left = 0;
        int top = 0;
        int right =
                mSelectedRegion.getWidth()
                        * mImageInfo.getWidth()
                        / mFullDraweeView.getLayoutConfig().width ;
        int bottom =
                mSelectedRegion.getHeight()
                        * mImageInfo.getHeight()
                        / mFullDraweeView.getLayoutConfig().height;
        LogUtil.error(TAG, "right = " + right + " ; bottom = " + bottom);
        ImageDecoder regionDecoder = createRegionDecoder(left, top, right, bottom);
        mRegionDraweeView.setController(
                Fresco.newDraweeControllerBuilder()
                        .setImageRequest(
                                ImageRequestBuilder.newBuilderWithSource(mUri)
                                        .setImageDecodeOptions(
                                                ImageDecodeOptions.newBuilder()
                                                        .setCustomImageDecoder(regionDecoder)
                                                        .build())
                                        .build())
                        .build());
    }

    private ImageDecoder createRegionDecoder(int left, int top, int right, int bottom) {
        return new RegionDecoder(
                Fresco.getImagePipelineFactory().getPlatformDecoder(), new Rect(left, top, right, bottom));
    }

    public static class RegionDecoder implements ImageDecoder {

        private final PlatformDecoder mPlatformDecoder;
        private final Rect mRegion;

        public RegionDecoder(PlatformDecoder platformDecoder, Rect region) {
            mPlatformDecoder = platformDecoder;
            mRegion = region;
        }

        @Override
        public CloseableImage decode(
                EncodedImage encodedImage,
                int length,
                QualityInfo qualityInfo,
                ImageDecodeOptions options) {
            CloseableReference<PixelMap> decodedBitmapReference =
                    mPlatformDecoder.decodeJPEGFromEncodedImageWithColorSpace(
                            encodedImage, options.bitmapConfig, mRegion, length, options.colorSpace);
            try {
                LogUtil.error(TAG,"region decode A decodedBitmapReference:"+decodedBitmapReference);
                return new CloseableStaticBitmap(decodedBitmapReference, qualityInfo, 0);
                //重点查看这里返回后，代码去哪里了？
            } finally {
                CloseableReference.closeSafely(decodedBitmapReference);
            }
        }
    }
}
